/*
 * Copyright 2010 Pierre Heinzerling, Uwe Janner, Patrick Wright
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const MAX_DISPLAY_LEN = 40;
const DEFAULT_TAGS_NEW_ITEM = "";
const MAGIC_ALL_TAG = "all";

// store current tab url, makes it easily available between function calls and callbacks
var current_url;
var otherThemesCount = new Array();

// themes modified since we last opened them; pulled from bg() when we open
var themes_modified;

// user's invitation to current theme (if any)
var theme_and_invitation;

// remember the selected text of current tab:
var selectedTextOfCurrentTab;

window.onLoad = onPopupLoad();

function displayForTheme(theme) {
	lockNoteBox(true);
    showCurrentTheme(theme);
    serverGetTheme(theme, theme.key.id, function(themeAndInvitation) {
        var themeReload = themeAndInvitation.theme;
        theme_and_invitation = themeAndInvitation;

        lsStoreCurrentTheme(themeReload);
        showCurrentTheme(themeReload);

        // get url and title from current tab; use these in top panel
        chrome.tabs.getSelected(null, function(tab) {
            current_url = tab.url;

            resetLinkView(current_url, tab.title);
            reloadLinksTable();
        });
        serverListUserThemes(showThemesList);
        serverListAllThemeInvitations(themeReload, showInvitationsSentList);
        serverListThemeInvitationsTo(showInvitationsToList);
    });
}

function switchToScratchpad() {
	serverGetThemeScratchpad(getCurrentUserEmail(), function(theme) {
		lsStoreCurrentTheme(theme);
		displayForTheme(theme);
	});
}

function toggleTestDebug() {
	$("#test_div").toggle();
}

function onPopupLoad() {
	otherThemesCount["own"] = 0;
	otherThemesCount["others"] = 0;
	setTimeout(
			function () {
				toggleLoginImage(bg().loginState.email);
				// please mr eventManager, notify me too:
				bg().eventManager.registerLoginStateChanged( toggleLoginImage);

				// onclick behaviour for connect/disconnect:
				$('#loginStateLink').click(toggleLogin);

				var currentTheme;
				if (lsHasCurrentTheme()) {
					var theme = lsGetCurrentTheme();
					displayForTheme(theme);
				} else {
					switchToScratchpad();
				}

                if (bg().havePendingNotification()) {
                    themes_modified = bg().listModifiedThemes();
                    bg().clearPendingNotifications();
                    var i;
                    for(i=0;i<themes_modified.length;i++) {
                        var t = themes_modified[i];
                    }
                }
				
				$("a.collapser").each(
					function(index) {
						$(this).bind(
							"click", function(){
								
								$(this).next("div.collapsible").slideToggle("fast", function() {
									if($(this).prev("a").hasClass("collapserClosed")){
										$(this).prev("a").addClass("collapserOpen")
										$(this).prev("a").removeClass("collapserClosed")
									}else{
										$(this).prev("a").addClass("collapserClosed")
										$(this).prev("a").removeClass("collapserOpen")
									}
								});
							}
						)
					}
				);

				selectedTextOfCurrentTab = "";
				chrome.tabs.getSelected(null, function(tab) {
					chrome.tabs.sendRequest(tab.id, {getSelection: "getSelection"}, function(response) {
						  if( response.message ){
							  selectedTextOfCurrentTab = response.message;
						  }
					  });
					});
				
				writeLog("popup initialized (some actions may be deferred)");
			}, 0);
}


function addThemeLinkToTable(link, comments) {
	if (link == null) {
		$("#no_links").show();
		//$("#current_links").hide();
	} else {
		if ($("#links_table div.linkItem  a#link" + link.key.id).length > 0) { return; }
		var theme = lsGetCurrentTheme();
		var em = getCurrentUserEmail();
		var style = "";
		var linkHasChanged = false;
		if (comments) {
			// flip through the comments to see if this user voted it down, if so, just skip it
			for (var i = 0; i < comments.length; i++) {
				var comment = comments[i];
				if (comment.userEmail == em && !comment.isGood) {
                    return;
                }
                if (theme_and_invitation) {
                    if (comment.userEmail != em && comment.themeLastUpdateCounter > theme_and_invitation.lastRetrievedCounter) {
                        linkHasChanged = true;
                    }
                }
			}
		}
        if (linkHasChanged) {
            style += "font-weight: bold;";
        }
		$("#no_links").hide();
		//$("#current_links").show();

		var tbl = elem("links_table");
		var del = "<a href='javascript:deleteLink(\"" + link.key.id + "\")' title='Dont link so...' class=\"unlikeBtn\"><img src='icons/lightning_delete.png'></a>";

		var scoreTxt = "<div class=\"scoreTxt\">(+" + link.score + ")</div>";
		var s = "";
		s += "<div class=\"linkItem\">";
		s += scoreTxt + del + "<a id=\"link" + link.key.id + "\" href='javascript:openInNewTab(\"" + link.uriString + "\")'><span style='" + style + "'>" + shorten(link.title) + "</span></a>";
		s += "</div>";
		tbl.innerHTML += s;

		if (link.uriString == current_url) {
			displayLink(current_url, link, comments);
		}
	}
}

function populateLinksTable() {
	showWaiting();
	serverListLinksForTheme(lsGetCurrentTheme().key.id, addThemeLinkToTable, function(cnt) {
		notWaiting();
        if (cnt) {
			if (cnt > 0) {
				$("#show_overview_div").show();
				$("#open_all_div").show();
				$("div.linkItem").each(function(index){
					$(this).hover(
						function(){ $(this).children("a.unlikeBtn").css("visibility", "visible"); },
						function(){ $(this).children("a.unlikeBtn").css("visibility", "hidden"); }
					);
				});
			} else {
				$("#show_overview_div").hide();
				$("#open_all_div").hide();
			}
		}
	});
}

function reloadLinksTable() {
	elem("links_table").innerHTML = "";
	populateLinksTable();
}

function applyChangesToCurrentLink() {
	var note = elem("note").value;
	var tags = extractTagsFrom(note);
	var tagCsv = "";
	var sep = "";
	for (var t in tags) {
		tagCsv += sep + t;
		sep = ",";
	}

	var url = elem("current_url").value;
	var title = elem("current_title").value;

	showWaiting();
	serverSubmitLink(lsGetCurrentTheme().key.id, url, title, note, tagCsv, tags, function(newLink) {
		notWaiting();
		addThemeLinkToTable(newLink, null);
	});
}

function postNewTheme() {
	serverAddTheme(elem("submit_theme_name").value, function (newTheme) {
		lsStoreCurrentTheme(newTheme);
		displayForTheme(newTheme);
	});
}

function postNewInvitation() {
	serverAddInvitation(lsGetCurrentTheme(), elem("submit_invitation").value, function (theme, invite) {
		displayForTheme(theme);
	});

}

function deleteLink(linkId) {
	serverDeleteLink(linkId, function(theme) {
        lsStoreCurrentTheme(theme);
		resetLinkView(elem("current_url").value, elem("current_title").value);
		reloadLinksTable();
	});
}

function resetLinkView(url, title) {
	// this is the default view. settings here will be overridden if retrieveAndDisplayLink() returns
	// a link for the database for the current URL. Assume what is applied here is for new URLs which have not
	// been saved on the server
	elem("display_url").innerHTML = shorten(url);
	elem("current_url").value = url;
	//elem("display_title").innerHTML = shorten(title);
	//elem("display_title").value = shorten(title);
	elem("current_title").value = title;
	elem("note").value = DEFAULT_TAGS_NEW_ITEM + selectedTextOfCurrentTab;
	elem("other_user_notes").innerHTML = "";
	lockNoteBox(false);
}

function displayLink(forUrl, link, comments) {
	// set display of popup to the link identified by url
	var theme = lsGetCurrentTheme();
	if (theme) {
		elem("display_url").innerHTML = shorten(link.uriString);
		elem("current_url").value = link.uriString;
		elem("current_title").value = link.title;
		if (comments) {
            var e = elem("other_user_notes");
            var s = "";
            var i;
            for (i = 0; i < comments.length; i++) {
                var cmt = comments[i];
                if (cmt.userEmail == getCurrentUserEmail()) {
                	lockNoteBox(false);
					elem("note").value = cmt.note + "\n" + selectedTextOfCurrentTab;
				} else {
					if (cmt.note.length == 0) {
						if (cmt.isGood) {
							s += cmt.userEmail + ": Nothing to say, but likes it.<br />";
						} else {
							s += cmt.userEmail + ": Nothing to say. Doesn't like it.<br />";
						}
					} else {
						s += "<i>" + cmt.userEmail + "<i>: " + cmt.note + "<br />";
					}
				}
			}
			e.innerHTML = s;
		} else {
			writeLog("no comments for link " + link.id);
		}
		lockNoteBox(false);
	} else {
		writeLog("Can't retrieve link - no current theme");
	}
}

function showCurrentTheme(theme) {
	if (theme) {
		$("#new_theme_div").show();
		if (isScratchPadTheme(theme)) {
			$("#current_theme_div").hide();
			$("#switch_to_scratchpad_div").hide();
			elem("current_context").innerHTML = theme.name;
		} else {
			$("#current_theme_div").show();
			$("#switch_to_scratchpad_div").show();
			$("#icon_bar").show();
			var st = theme.name; // + "&nbsp;(" + theme.key.id + ")";
			elem("current_context").innerHTML = st;
		}
		$("#theme_owner").show();
		if (theme.ownerEmail == getCurrentUserEmail()) {
			elem("theme_owner").innerHTML = "";
			$("#decline_theme_div").hide();
		} else if (getCurrentUserEmail() != "") {
			elem("theme_owner").innerHTML = "Started by " + theme.ownerEmail;
			$("#decline_theme_div").html("<a href='#' onclick='declineInvitation()'>No, thanks!</a>").show();
		}
	}
}

function declineInvitation() {
	serverDeclineInvitation(lsGetCurrentTheme(), function () {
		switchToScratchpad();
	});
}

function isScratchPadTheme(theme) {
	return theme.name == 'ScratchPad';
}

function lockNoteBox(lock){
	if (lock) {
		$("div#currentPageCtnForm").hide();
		$("div#currentPageCtnLoader").show();
	} else {
		$("div#currentPageCtnForm").show();
		$("div#currentPageCtnLoader").hide();
	}
	
}

function switchCurrentThemeTo(themeId) {
	lockNoteBox(true);
	serverGetTheme(null, themeId, function(themeAndInvitation) {
        var theme = themeAndInvitation.theme;
        theme_and_invitation = themeAndInvitation;
		lsStoreCurrentTheme(theme);
        displayForTheme(theme);
    });
}

function showThemesList(themes) {
	if (themes) {
		// count # other than scratchpad
		var cnt = 0;
		// one column per theme (takes less space)
		var currentTheme = lsGetCurrentTheme();
        var onlyCurrentThemeIsModified = true;
		var themeLinks = "";
		for (var i = 0; i < themes.length; i++) {
			var theme = themes[i];
			if (currentTheme.key.id == theme.key.id || isScratchPadTheme(theme)) {
				continue;
			}
			cnt += 1;
			var themeDesc = theme.name; // + " (" + theme.key.id + ")";

            var style = "";
            if (themes_modified) {
                var j;
                for (j=0; j<themes_modified.length;j++) {
                    var mt = themes_modified[j];
                    if (mt.key.id == theme.key.id) {
                        style = "font-weight:bold";
                    }
                    if (mt.key.id != currentTheme.key.id) {
                        onlyCurrentThemeIsModified = false;
                    }
                }
            }
            // TODO: decline Invitation from here
            //themeLinks += "<a href='javascript:declineInvitation(\"" + link.key.id + "\")' title='Dont link so...' class=\"unlikeBtn\"><img src='icons/lightning_delete.png'></a>";
			themeLinks += "<a class=\"themeLink\" href='#' style='" + style + "' onclick='switchCurrentThemeTo(" + theme.key.id + ")'>" + themeDesc + "</a> ";
		}
		$("#themes_div").toggle(cnt > 0);
		setOtherThemesCount(cnt, null);
		elem("themes_desc").innerHTML = (cnt > 0) ? ("Your Themes: " + themeLinks) : "";
        if (themes_modified && !onlyCurrentThemeIsModified) {
            $("#view_themes_div").show();
            themes_modified = null;
        }
    } else {
		$("#themes_div").hide();
	}
}

function showInvitationsSentList(invites) {
	if (invites && invites.length > 0) {
		var howMany = invites.length;
		var i;
		var invLinks = "";
		// always show owner
		invLinks += "&nbsp;&nbsp;" + lsGetCurrentTheme().ownerEmail + " (owner)<br />";
		var cnt = 1;
		for (i = 0; i < howMany; i++) {
			var inv = invites[i];
			if (inv.toEmail != getCurrentUserEmail()) {
				cnt++;
				invLinks += "&nbsp;&nbsp;" + inv.toEmail + "<br />";
			}
		}
		if (cnt > 0) {
			elem("invites_from_desc").innerHTML = cnt + " other people in this theme:<br />" + invLinks;
		}
	} else {
		elem("invites_from_desc").innerHTML = "You have not invited anyone yet.";
	}
}
function setOtherThemesCount(own, others) {
	if (own != null){
		otherThemesCount["own"]	= own;
	}else if (others != null){
		otherThemesCount["others"]	= others;
	}
	elem("otherThemes").innerHTML = "Other Themes (" + (otherThemesCount["own"] + otherThemesCount["others"]) + ")";
}
function showInvitationsToList(invites) {
	if (invites && invites.length > 0) {
		elem("invites_open").innerHTML = "";
		var howMany = invites.length;
		var invLinks = "";
		var cnt = 0;

		var foundOneNotCurrent = false;
		for (var i = 0; i < howMany; i++) {
			var inv = invites[i];
			if (inv.theme.id == lsGetCurrentTheme().key.id) {
				continue;
			}
			foundOneNotCurrent = true;
			cnt++;
			// get theme for this invitation
			serverGetTheme(null, inv.theme.id, function(themeAndInvitation) {
				var theme = themeAndInvitation.theme;
				invLinks = "<a class=\"themeLink\" href='#' onclick='switchCurrentThemeTo(" + theme.key.id + ")'>" + theme.name + "</a> ";
				elem("invites_open").innerHTML += invLinks;
			});
		}
		setOtherThemesCount(null, cnt);
		//$("#invites_div").show();
		$("#invites_div").toggle(foundOneNotCurrent);
	} else {
		$("#invites_div").hide();
		elem("invites_open").innerHTML = "No open invitations.";
	}
}

//
// utility functions
//
function extractTagsFrom(text) {
	var re = /(^|\s)#(\w+)/g;
	var m = text.match(re);
	var tagsUnique = new Array();
	if (m) {
		for (i = 0; i < m.length; i++) {
			var aTag = m[i].trim().substring(1);
			tagsUnique[aTag] = aTag; // use it like a map to pick out unique values
		}
	}
	var tags = new Array();
	for (var t in tagsUnique) {
		tags.push(t);
	}

	return tags;
}

function shorten(text) {
	if (text.length > MAX_DISPLAY_LEN) {
		text = text.substring(0, MAX_DISPLAY_LEN) + "...";
	}
	return text;
}

function openInNewTab(toUrl) {
	lockNoteBox(true);
	chrome.tabs.getAllInWindow(null, function (tabs) {
		var i;
		var found;
		for (i = 0; i < tabs.length; i++) {
			var tab = tabs[i];
			if (tab.url == toUrl) {
				chrome.tabs.update(tab.id, {selected:true}, null);
				found = true;
				break;
			}
		}
		if (!found) {
			chrome.tabs.create({url:toUrl}, null);
		}
	});
	serverFindLink(lsGetCurrentTheme(), toUrl, function(link) {
		serverFindCommentsForLink(link, function(comments) {
			displayLink(toUrl, link, comments);
		})
	});
}

function openAllInNewTabs() {
	if (lsHasCurrentTheme()) {
		var theme = lsGetCurrentTheme();
		serverListLinksForTheme(theme.key.id, function(link, comments) {
			openInNewTab(link.uriString);
			serverIncrementVisitCount(theme.key.id, link.uriString, function(howMany) {});
		}, null);
	}
}

function showOverviewPage() {
	if (lsHasCurrentTheme()) {
		var theme = lsGetCurrentTheme();
		var links = new Array();
		serverListLinksForTheme(theme.key.id, function (ln, cmt) {
			links.push({link: ln, comments: cmt});
		}, function(howMany) {
			bg().showOverview(theme, links);
		});
	}
}
function getCurrentUserEmail() {
	return bg().loginState.email;
}

function toggleLogin() {
	if (bg().loginState.email) {
		bg().loginState.logout();
	} else {
		bg().loginState.login();
	}
}

function toggleLoginImage(email){
	var imageSrc = "icons/" + (email ? "" : "dis") + "connected.png"; 
	$('#loginStateIcon').attr("src",imageSrc);
	$('#loginStateIcon').parent("a").attr("title", (email ? "Logout" : "Login"));
}
